import { ColorSchema, CSLine, ParameterObjectType } from '@amcax/base';
import { Vector3, Vector3Tuple } from 'three-legacy';
import { MeasureLabel } from './Label';
import { MeasureObject } from './renderObject';
import { MeasureDistanceResultWithLabel } from './types';

export enum DistanceLineType {
  Full = 'Full',
  X = 'X',
  Y = 'Y',
  Z = 'Z',
}

export const MEASURE_DISTANCE_COLORS = {
  [DistanceLineType.Full]: 0x000001,
  [DistanceLineType.X]: 0xf26f6f,
  [DistanceLineType.Y]: 0x31a888,
  [DistanceLineType.Z]: 0x51a4db,
};

export class DistanceLine extends CSLine {
  private defaultColor: number;

  constructor(
    measureResult: MeasureDistanceResultWithLabel,
    // 是完整/X/Y/Z分量
    public type: DistanceLineType,
    // 是中心距离还是最小距离
    distanceType: 'min' | 'center',
  ) {
    const start = measureResult.geometry.pt1;
    const end = measureResult.geometry.pt2;

    const xStart: Vector3Tuple = [...start];
    const yStart: Vector3Tuple = [end[0], start[1], start[2]];
    const zStart: Vector3Tuple = [end[0], end[1], start[2]];
    const vertexes = {
      [DistanceLineType.Full]: [start, end],
      [DistanceLineType.X]: [xStart, yStart],
      [DistanceLineType.Y]: [yStart, zStart],
      [DistanceLineType.Z]: [zStart, end],
    }[type];

    const value = {
      [DistanceLineType.Full]: measureResult.value,
      [DistanceLineType.X]: measureResult.xValue,
      [DistanceLineType.Y]: measureResult.yValue,
      [DistanceLineType.Z]: measureResult.zValue,
    }[type];

    const labelPosition = {
      [DistanceLineType.Full]: measureResult.labelPosition,
      [DistanceLineType.X]: measureResult.labelPositionX,
      [DistanceLineType.Y]: measureResult.labelPositionY,
      [DistanceLineType.Z]: measureResult.labelPositionZ,
    }[type];

    const labelEnd = distanceType === 'min' ? '最小值' : '中心';

    const label = {
      [DistanceLineType.Full]: labelEnd,
      [DistanceLineType.X]: `X${labelEnd}`,
      [DistanceLineType.Y]: `Y${labelEnd}`,
      [DistanceLineType.Z]: `Z${labelEnd}`,
    }[type];

    const color = MEASURE_DISTANCE_COLORS[type];

    super({
      vertexs: vertexes.map((v) => new Vector3(...v)),
      color,
      lineWidth: 3,
    });

    this.defaultColor = color;

    this.label = new MeasureLabel({
      label,
      value,
      type: ParameterObjectType.Length,
      lineTo: this,
      position: vertexes[0].map(
        (axisStart, index) => (axisStart + vertexes[1][index]) / 2,
      ) as Vector3Tuple,
      labelColor: MEASURE_DISTANCE_COLORS[type],
      labelPosition,
    });

    this.add(this.label);
  }

  label: MeasureLabel;

  destroy() {
    super.destroy();
    this.label?.destroy();
  }

  getRootObject() {
    let currentParent = this.parent;

    while (currentParent != null) {
      if (currentParent instanceof MeasureObject) {
        return currentParent;
      }
      currentParent = currentParent.parent;
    }

    return null;
  }

  isHovered: boolean;
  isSelected: boolean;

  setHover(val: boolean) {
    this.isHovered = val;
    this.label.setHover(val);
    this.renderHighlight();
  }
  setSelect(val: boolean) {
    this.isSelected = val;
    this.label.setSelect(val);
    this.renderHighlight();
  }

  renderHighlight() {
    let color = this.defaultColor;
    if (this.isHovered) {
      color = ColorSchema.hover.edge;
    } else if (this.isSelected) {
      color = ColorSchema.select.edge;
    }
    this.setColor(color);
  }
}
